﻿using NetTopologySuite.Features;
using NetTopologySuite.Geometries;
using NetTopologySuite.IO.Esri.Dbf;
using NetTopologySuite.IO.Esri.Shapefiles.Readers;
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace NetTopologySuite.IO.Esri.Test.Geometries
{
    /// <summary>
    /// Tests for MultiPolygon having a polygon inside the hole.
    /// https://github.com/NetTopologySuite/NetTopologySuite.IO.ShapeFile/pull/80#issuecomment-1019816823
    /// 
    /// </summary>
    internal class MultipolygonWithPolygonInHole
    {
        private static string Wkt = @"
            MULTIPOLYGON (
                (
                    (
                        -124.134 -79.199, -124.141 -79.316, -124.164 -79.431, -124.202 -79.542, -124.254 -79.647, -124.319 -79.745, -124.396 -79.833, -124.484 -79.91,
                        -124.582 -79.975, -124.687 -80.027, -124.798 -80.065, -124.913 -80.088, -125.03 -80.095, -125.147 -80.088, -125.262 -80.065, -125.373 -80.027,
                        -125.478 -79.975, -125.576 -79.91, -125.664 -79.833, -125.741 -79.745, -125.806 -79.647, -125.858 -79.542, -125.896 -79.431, -125.919 -79.316,
                        -125.926 -79.199, -125.919 -79.082, -125.896 -78.967, -125.858 -78.856, -125.806 -78.751, -125.741 -78.653, -125.664 -78.565, -125.576 -78.488,
                        -125.478 -78.423, -125.373 -78.371, -125.262 -78.333, -125.147 -78.31, -125.03 -78.303, -124.913 -78.31, -124.798 -78.333, -124.687 -78.371,
                        -124.582 -78.423, -124.484 -78.488, -124.396 -78.565, -124.319 -78.653, -124.254 -78.751, -124.202 -78.856, -124.164 -78.967, -124.141 -79.082, -124.134 -79.199
                    ),
                    (
                        -124.438 -79.199, -124.443 -79.122, -124.459 -79.046, -124.483 -78.973, -124.518 -78.903, -124.561 -78.839, -124.612 -78.781, -124.67 -78.73,
                        -124.734 -78.687, -124.804 -78.652, -124.877 -78.628, -124.953 -78.612, -125.03 -78.607, -125.107 -78.612, -125.183 -78.628, -125.256 -78.652,
                        -125.326 -78.687, -125.39 -78.73, -125.448 -78.781, -125.499 -78.839, -125.542 -78.903, -125.577 -78.973, -125.601 -79.046, -125.617 -79.122,
                        -125.622 -79.199, -125.617 -79.276, -125.601 -79.352, -125.577 -79.425, -125.542 -79.495, -125.499 -79.559, -125.448 -79.617, -125.39 -79.668,
                        -125.326 -79.711, -125.256 -79.746, -125.183 -79.77, -125.107 -79.786, -125.03 -79.791, -124.953 -79.786, -124.877 -79.77, -124.804 -79.746,
                        -124.734 -79.711, -124.67 -79.668, -124.612 -79.617, -124.561 -79.559, -124.518 -79.495, -124.483 -79.425, -124.459 -79.352, -124.443 -79.276, -124.438 -79.199
                    )
                ),
                (
                    (
                        -124.582 -79.199, -124.586 -79.257, -124.597 -79.315, -124.616 -79.371, -124.642 -79.423, -124.674 -79.472, -124.713 -79.516, -124.757 -79.555,
                        -124.806 -79.587, -124.858 -79.613, -124.914 -79.632, -124.972 -79.643, -125.03 -79.647, -125.088 -79.643, -125.146 -79.632, -125.202 -79.613,
                        -125.254 -79.587, -125.303 -79.555, -125.347 -79.516, -125.386 -79.472, -125.418 -79.423, -125.444 -79.371, -125.463 -79.315, -125.474 -79.257,
                        -125.478 -79.199, -125.474 -79.141, -125.463 -79.083, -125.444 -79.027, -125.418 -78.975, -125.386 -78.926, -125.347 -78.882, -125.303 -78.843,
                        -125.254 -78.811, -125.202 -78.785, -125.146 -78.766, -125.088 -78.755, -125.03 -78.751, -124.972 -78.755, -124.914 -78.766, -124.858 -78.785,
                        -124.806 -78.811, -124.757 -78.843, -124.713 -78.882, -124.674 -78.926, -124.642 -78.975, -124.616 -79.027, -124.597 -79.083, -124.586 -79.141, -124.582 -79.199
                    ),
                    (
                        -124.896 -79.199, -124.897 -79.181, -124.9 -79.164, -124.906 -79.148, -124.914 -79.132, -124.923 -79.117, -124.935 -79.104, -124.948 -79.092,
                        -124.963 -79.083, -124.979 -79.075, -124.995 -79.069, -125.012 -79.066, -125.03 -79.065, -125.048 -79.066, -125.065 -79.069, -125.081 -79.075,
                        -125.097 -79.083, -125.112 -79.092, -125.125 -79.104, -125.137 -79.117, -125.146 -79.132, -125.154 -79.148, -125.16 -79.164, -125.163 -79.181,
                        -125.164 -79.199, -125.163 -79.217, -125.16 -79.234, -125.154 -79.25, -125.146 -79.266, -125.137 -79.281, -125.125 -79.294, -125.112 -79.306,
                        -125.097 -79.315, -125.081 -79.323, -125.065 -79.329, -125.048 -79.332, -125.03 -79.333, -125.012 -79.332, -124.995 -79.329, -124.979 -79.323,
                        -124.963 -79.315, -124.948 -79.306, -124.935 -79.294, -124.923 -79.281, -124.914 -79.266, -124.906 -79.25, -124.9 -79.234, -124.897 -79.217, -124.896 -79.199
                    )
                )
            )";


        [Test]
        public void WriteMultipolygonWithPolygonInHole()
        {
            var wktReader = new WKTReader();
            var wktMultiPolygon = (MultiPolygon)wktReader.Read(Wkt);
            var feature = new Feature(wktMultiPolygon, new AttributesTable());

            var tempShpPath = TestShapefiles.GetTempShpPath();
            Shapefile.WriteAllFeatures(Enumerable.Repeat(feature, 1), tempShpPath);
            var shpMultiPolygon = (MultiPolygon)Shapefile.ReadAllGeometries(tempShpPath).First();
            TestShapefiles.DeleteShp(tempShpPath);

            Assert.IsTrue(shpMultiPolygon.EqualsExact(wktMultiPolygon), "SHP MultiPolygon is not equal to WKT MultiPolygon.");
        }

        //https://github.com/NetTopologySuite/NetTopologySuite.IO.ShapeFile/issues/70
        [Test]
        public void TestShapeFileIssue70()
        {
            var options = new ShapefileReaderOptions()
            {
                GeometryBuilderMode = GeometryBuilderMode.QuickFixInvalidShapes
            };
            var shpPath = TestShapefiles.PathTo("Example_70.shp");
            var features = Shapefile.ReadAllFeatures(shpPath, options);
            var problematicFeature = features.First(f => f.Attributes["FID"].Equals(481));
            var multiPolygon = (MultiPolygon)problematicFeature.Geometry;
            var normalizedMultiPolygon = (MultiPolygon)multiPolygon.Normalized();
            Assert.AreEqual(1, 1);

        }
    }
}
